package com.common.dongqiuhui.platform.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.text.TextUtils;

import com.common.dongqiuhui.apps.comm.tools.BallLog;
import com.common.nostra13.universalimageloader.utils.StorageUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Locale;

public class ImageUtil {
	/** 图片最大尺寸 */
	public static final int MAX_INSERT_FILE_SIZE = 500 * 1024;
	private static final String TAG = ImageUtil.class.getSimpleName();
	public static String getPhotoPath(Context context, String path, int mBitmapW, int mBitmapH) {
		try {
			path = ImageUtil.compressImage(context, path, mBitmapW, mBitmapH, 0);
		} catch (Throwable e){
			e.printStackTrace();
            gc();
		}
		return path;
	}
	public static String compressImage(Context context, String path, int reqWidth, int reqHeight, int degrees) {
		Bitmap temp = getBitmap(path, reqWidth, reqHeight, degrees, true);
		return compressImage(context, temp, reqWidth, reqHeight);
	}
	
	/**
	 * 获取文件的Bitmap
	 * 
	 * @param fileName
	 *            :文件名
	 * @param reqWidth
	 *            :显示宽度
	 * @param reqHeight
	 *            :显示高度
	 * @param degrees
	 *            :旋转角度
	 * @return Bitmap
	 */
	public static Bitmap getBitmap(String fileName, int reqWidth, int reqHeight, int degrees, boolean scale) {
		Bitmap bmp = null;
		try {
            // 不能使用loadImageSync, 心情生成临时文件路径相同, 缓存中有老的bitmap
            Options options = new Options();
            if ((reqWidth > 0) || (reqHeight > 0)) {
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeFile(fileName, options);
                options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
            }
            options.inPurgeable = true;
            options.inInputShareable = true;
            options.inPreferredConfig = Bitmap.Config.RGB_565;
            options.inJustDecodeBounds = false;
            bmp = BitmapFactory.decodeFile(fileName, options);
			if (null != bmp) {
				if (scale) {
					bmp = scaleBitmap(bmp, reqWidth, reqHeight);
				}
				int rotate = 0;
				ExifInterface exifInterface = new ExifInterface(fileName);
				int result = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);

				switch (result) {
				case ExifInterface.ORIENTATION_ROTATE_90:
					rotate = 90;
					break;
				case ExifInterface.ORIENTATION_ROTATE_180:
					rotate = 180;
					break;
				case ExifInterface.ORIENTATION_ROTATE_270:
					rotate = 270;
					break;
				default:
					break;
				}
				rotate += degrees;
				if (0 != rotate) {
					Matrix matrix = new Matrix();
					matrix.setRotate(rotate);
					Bitmap rotateBitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
					if (null != rotateBitmap) {
						bmp = rotateBitmap;
					}
				}
			}
		} catch (Throwable e) {
			BallLog.e(TAG, "getBitmap reqWidth[" + reqWidth + "] reqHeighte[" + reqHeight + "] e[" + e.toString() + "]");
            gc();
		}
		return bmp;
	}
	
	public static String compressImage(Context context, Bitmap bmp, int reqWidth, int reqHeight) {
		String result = null;
		Bitmap temp = bmp;
		ByteArrayOutputStream baos = null;
		try {
			if (null != temp) {
				temp = scaleBitmap(temp, reqWidth, reqHeight);
				// LogUtil.i(TAG, "compressImage temp[" + temp + "] bmp[" + bmp + "]");
				baos = new ByteArrayOutputStream();
				temp.compress(CompressFormat.JPEG, 100, baos);
				int options = 100;
				int length = baos.toByteArray().length;
				while (length > MAX_INSERT_FILE_SIZE) {
					baos.reset();
					if (length > MAX_INSERT_FILE_SIZE * 5) {
						options -= 50;
					} else if (length > MAX_INSERT_FILE_SIZE * 3) {
						options -= 30;
					} else if (length > MAX_INSERT_FILE_SIZE * 2) {
						options -= 10;
					} else {
						options -= 5;
					}
					temp.compress(CompressFormat.JPEG, options, baos);
					length = baos.toByteArray().length;
				}
				result = saveImageFile(context, baos.toByteArray(), CompressFormat.JPEG, "");
			}
		} catch (Throwable e) {
			BallLog.e(TAG, "compressImage e[" + e.toString() + "]");
            gc();
			result = null;
        }finally {
            if(null!=bmp && !bmp.isRecycled()){
                bmp.recycle();
                bmp = null;
            }
            if (null!=temp && !temp.isRecycled()){
                temp.recycle();
                temp = null;
            }
            gc();
        }

		return result;
	}
	
	public static String saveImageFile(Context context, byte[] data, CompressFormat format, String pathName) {
		String path = "";
		try {
			String suffix = "";
			switch (format) {
			case JPEG:
				suffix = ".jpg";
				break;
			case PNG:
				suffix = ".png";
				break;
			case WEBP:
				suffix = ".webp";
				break;
			}

			String folder = getCacheDirectory(context);
			String fileName = TextUtils.isEmpty(pathName) ? getTempFileName() + suffix : pathName + suffix;
            if (folder.endsWith(File.separator)) {
                path = folder + fileName;
            } else {
                path = folder + File.separator + fileName;
            }
			File file = new File(path);
			if (file.exists()) {
				if (file.isFile()) {
					if (false == file.delete()) {
						BallLog.i(TAG, "saveImageFile delete fail");
						return path;
					}
				} else {
					BallLog.i(TAG, "saveImageFile folder err");
					return path;
				}
			}
			file.createNewFile();
			OutputStream outStream = new FileOutputStream(file);
			outStream.write(data);
			outStream.close();
		} catch (Throwable e) {
			BallLog.e(TAG, "saveImageFile e[" + e.toString() + "]");
			path = "";
		}
		return path;
	}

	/**
	 * 获取缓存路径
	 * 
	 * @param context
	 *            ：上下文
	 * @return：返回缓存路径，可能为null
	 */
	public static String getCacheDirectory(Context context) {
		return StorageUtils.getCacheDirectory(context).getAbsolutePath();
	}

	public static byte[] bitmapToByteArray(final Bitmap bmp, int quality, final boolean needRecycle) {
		byte[] result = null;
		try {
			ByteArrayOutputStream output = new ByteArrayOutputStream();
			bmp.compress(CompressFormat.JPEG, quality, output);

			result = output.toByteArray();
			output.close();

			if (needRecycle) {
				bmp.recycle();
			}
		} catch (Throwable e) {
			BallLog.e(TAG, "bitmapToByteArray e[" + e + "]");
            gc();
		}

		return result;
	}
	
	/**
	 * 计算图片sample
	 * 
	 * @param options
	 *            :图片options
	 * @param reqWidth
	 *            :显示宽度
	 * @param reqHeight
	 *            :显示高度
	 * @return 图片sample
	 */
	public static int calculateInSampleSize(Options options, int reqWidth, int reqHeight) {
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {
			final int halfHeight = height / 2;
			final int halfWidth = width / 2;

			// Calculate the largest inSampleSize value that is a power of 2 and
			// keeps both
			// height and width larger than the requested height and width.
			while (((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth)
					|| ((halfHeight / inSampleSize) > 2048) || ((halfWidth / inSampleSize) > 2048)) {
				inSampleSize *= 2;
			}
		}

		return inSampleSize;
	}
	
	public static final Bitmap scaleBitmap(Bitmap bmp, int reqWidth, int reqHeight) {
		Bitmap temp = bmp;
		try {
			System.gc();
			Runtime.getRuntime().gc();
			if (null != temp) {
				if ((temp.getWidth() > reqWidth) || (temp.getHeight() > reqHeight)) {
					float scal = 1.0F;
					float scalW = (float) reqWidth / (float) temp.getWidth();
					float scalH = (float) reqHeight / (float) temp.getHeight();
					if (scalW < scalH) {
						scal = scalW;
					} else {
						scal = scalH;
					}
					Matrix matrix = new Matrix();
					matrix.setScale(scal, scal);
					temp = Bitmap.createBitmap(temp, 0, 0, temp.getWidth(), temp.getHeight(), matrix, true);
					if (null == temp) {
						temp = bmp;
					}
					System.gc();
					Runtime.getRuntime().gc();
				}
			}
		} catch (Throwable e) {
			BallLog.e(TAG, "scaleBitmap e[" + e + "]");
            gc();
		}
		return temp;
	}
	
    public static void gc() {
		BallLog.i(TAG, "gc");
        System.gc();
    }
    
	/**
	 * 使用当前时间戳拼接一个唯一的文件名
	 *
	 * @return
	 */
	public static String getTempFileName() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss_SS", Locale.getDefault());
		String fileName = format.format(new Timestamp(System.currentTimeMillis()));
		return fileName;
	}

}
